/****************************************************************
 *
 * Header Files
 *
 ***************************************************************/

#include "sal.h"
#include "ctc_cli.h"
#include "ctc_common.h"
#include "ctc_cli_common.h"
#include "ctc_xdata_cli.h"
#include "ctc_api.h"
#include "ctcs_api.h"
#include "ctc_error.h"
#include "ctc_debug.h"
#include "ctc_xdata.h"


#define XDATA_PATH "{logic-port-ext | hash-value |nat-l4-src-port| nat-l4-dst-port |ecmp-hash-high | aps-protecting-en |fwd-type |l3if-id | efd | dnat-l4-dst-port |  ingress-en }"

#define XDATA_PATH_STR  "    LOGIC_PORT_EXT    : CTC_XDATA_PATH_TYPE_IPE_BSR and CTC_XDATA_PATH_TYPE_BSR_EPE",\
                        "    HASH_VALUE        : CTC_XDATA_PATH_TYPE_IPE_BSR and CTC_XDATA_PATH_TYPE_BSR_EPE",\
                        "    NAT_L4_SRC_PORT   : CTC_XDATA_PATH_TYPE_IPE_BSR and CTC_XDATA_PATH_TYPE_BSR_EPE",\
                        "    NAT_L4_DST_PORT   : CTC_XDATA_PATH_TYPE_IPE_BSR and CTC_XDATA_PATH_TYPE_BSR_EPE",\
                        "    ECMP_HASH_HIGH    : CTC_XDATA_PATH_TYPE_IPE_BSR, CTC_XDATA_PATH_TYPE_BSR_EPE and CTC_XDATA_PATH_TYPE_IPE_LOCAL_BSR",\
                        "    APS_PROTECTING_EN : CTC_XDATA_PATH_TYPE_IPE_BSR and CTC_XDATA_PATH_TYPE_BSR_EPE",\
                        "    FWD_TYPE          : CTC_XDATA_PATH_TYPE_IPE_BSR and CTC_XDATA_PATH_TYPE_BSR_EPE",\
                        "    L3IF_ID           : CTC_XDATA_PATH_TYPE_IPE_LOCAL_BSR",\
                        "    EFD               : CTC_XDATA_PATH_TYPE_IPE_LOCAL_BSR",\
                        "    DNAT_L4_DST_PORT  : CTC_XDATA_PATH_TYPE_IPE_BSR and CTC_XDATA_PATH_TYPE_BSR_EPE",\
                        "    INGRESS_EN        : CTC_XDATA_PATH_TYPE_EPE_LOOP1"

int32 ctc_cmd_get_map_array(uint8 type, void *map,char* str)
{
    char   str_dst[30] ={'0'};
    uint8  pos = 0;
    uint8  start_pos = 0;
    uint8  arr_num=0;
    uint8  temp=0;
    uint32 arr_len = 5;
    uint32 map_arr[35][5]={{0,0,0,0,0}};
    uint32 ret = 0;

    if( str == NULL || *(str) !='[' )
    {
        arr_num = -1;
        return arr_num;
    }


    if( *(str) =='[' && *(str+1) ==']' )
    {
        arr_num = 0;
        return arr_num;
    }

    if( *(str) =='[' && *(str+1) !='[' )
    {
        arr_num = 1;
        for(;*(str+pos)!=']';pos++);
        strncpy(str_dst,str,pos+1);
        ctc_cmd_get_value_array("map", str_dst,map_arr[0],&arr_len, 2);
    }

    else
    {
        for(arr_num=0;*(str+pos)!=']';arr_num++)
        {
            if(arr_num >32)
            {
                return -1;
            }
            start_pos=pos;
            for(;*(str+pos)!=']';pos++);
            strncpy(str_dst,str+1+start_pos,pos-start_pos);
            ret = ctc_cmd_get_value_array("map", str_dst,map_arr[arr_num],&arr_len, 2);
            if(ret != 0)
            {
                return -1;
            }
            pos++;
            if(*(str+pos)!=']'&&*(str+pos+1)!='[')
            {
                return -1;
            }
        }
    }


    if(0 == type)
    {
        for(;temp<arr_num;temp++)
        {
            ((ctc_xdata_map_t*)map)[temp].width = map_arr[temp][0];
            ((ctc_xdata_map_t*)map)[temp].src_offset = map_arr[temp][1];
            ((ctc_xdata_map_t*)map)[temp].dst_offset = map_arr[temp][2];
        }
    }

    if(1 == type)
    {
        for(;temp<arr_num;temp++)
        {
            ((ctc_xdata_field_t*)map)[temp].width = map_arr[temp][0];
            ((ctc_xdata_field_t*)map)[temp].offset = map_arr[temp][1];
            ((ctc_xdata_field_t*)map)[temp].data = map_arr[temp][2];
            ((ctc_xdata_field_t*)map)[temp].mask = map_arr[temp][3];
            ((ctc_xdata_field_t*)map)[temp].flag = map_arr[temp][4];
        }
    }
    return arr_num;
}



CTC_CLI(ctc_cli_xdata_set_profile,
          ctc_cli_xdata_set_profile_cmd,
          "xdata ((post (scl | acl | tunnel | l3if | forward) ) | (scl | tunnel | mpls | fdb | ipuc | flow | acl | scl-egs | acl-egs)) (profile PROFILE) (array-map MAP)",
          "XData module",
          "Infomation after module,main is packetinfo",
          "SCL ingress",
          "ACL ingress",
          "TUNNEL",
          "L3IF",
          "FORWARD",
          "SCL ingress",
          "TUNNEL",
          "MPLS",
          "FDB-MACDA",
          "IPUC-IPDA",
          "FLOW",
          "ACL ingress",
          "SCL egress",
          "ACL egress",
          "Xdata profile id",
          "Xdata profile id value ",
          "Map array of generate xdata",
          "Two-dimensional Array,array number is ctc_xdata_map_t,format is [[WIDTH ,SRC-OFFSET,DST-OFFSET],[...]].For example based on fdb,[[4,48,48],[4,52,52],[4,56,56]]")
{   
    int32  ret = CLI_SUCCESS;
    ctc_xdata_prof_t xdata_prof;
    ctc_xdata_map_t  xdata_map[35];
    uint8 index = 0;
    uint8 post_idx = 1;
	uint8 ad_idx = 0;

    sal_memset(&xdata_prof, 0, sizeof(ctc_xdata_prof_t));
    sal_memset(&xdata_map, 0, sizeof(ctc_xdata_map_t)*35);

    index = CTC_CLI_GET_RANGE_INDEX("scl",post_idx,post_idx+1);
    if (0xFF != index)
    {
        xdata_prof.type = CTC_XDATA_PROF_TYPE_POST_SCL;
    }
    index = CTC_CLI_GET_RANGE_INDEX("acl",post_idx,post_idx+1);
    if (0xFF != index) 
    {
        xdata_prof.type = CTC_XDATA_PROF_TYPE_POST_ACL;
    }
    index = CTC_CLI_GET_RANGE_INDEX("tunnel",post_idx,post_idx+1);
    if (0xFF != index)
    {
        xdata_prof.type = CTC_XDATA_PROF_TYPE_POST_TUNNEL;
    }
    index = CTC_CLI_GET_RANGE_INDEX("l3if",post_idx,post_idx+1);
    if (0xFF != index)
    {
        xdata_prof.type = CTC_XDATA_PROF_TYPE_POST_L3IF;
    }
    index = CTC_CLI_GET_RANGE_INDEX("forward",post_idx,post_idx+1);
    if (0xFF != index)
    {
        xdata_prof.type = CTC_XDATA_PROF_TYPE_POST_FWD;
    }

    index = CTC_CLI_GET_RANGE_INDEX("scl",ad_idx,ad_idx+1);
    if (0xFF != index)
    {
        xdata_prof.type = CTC_XDATA_PROF_TYPE_DSSCL;
    }
    index = CTC_CLI_GET_RANGE_INDEX("tunnel",ad_idx,ad_idx+1);
    if (0xFF != index)
    {
        xdata_prof.type = CTC_XDATA_PROF_TYPE_DSTUNNEL;
    }
    index = CTC_CLI_GET_RANGE_INDEX("mpls",ad_idx,ad_idx+1);
    if (0xFF != index)
    {
        xdata_prof.type = CTC_XDATA_PROF_TYPE_DSMPLS;
    }
    index = CTC_CLI_GET_RANGE_INDEX("fdb",ad_idx,ad_idx+1);
    if (0xFF != index)
    {
        xdata_prof.type = CTC_XDATA_PROF_TYPE_DSMACDA;
    }
    index = CTC_CLI_GET_RANGE_INDEX("ipuc",ad_idx,ad_idx+1);
    if (0xFF != index)
    {
        xdata_prof.type = CTC_XDATA_PROF_TYPE_DSIPDA;
    }
    index = CTC_CLI_GET_RANGE_INDEX("flow",ad_idx,ad_idx+1);
    if (0xFF != index)
    {
        xdata_prof.type = CTC_XDATA_PROF_TYPE_DSFLOW;
    }
    index = CTC_CLI_GET_RANGE_INDEX("acl",ad_idx,ad_idx+1);
    if (0xFF != index)
    {
        xdata_prof.type = CTC_XDATA_PROF_TYPE_DSACL;
    }
    index = CTC_CLI_GET_RANGE_INDEX("scl-egs",ad_idx,ad_idx+1);
    if (0xFF != index)
    {
        xdata_prof.type = CTC_XDATA_PROF_TYPE_EGS_DSSCL;
    }
    index = CTC_CLI_GET_RANGE_INDEX("acl-egs",ad_idx,ad_idx+1);
    if (0xFF != index)
    {
        xdata_prof.type = CTC_XDATA_PROF_TYPE_EGS_DSACL;
    }

    index = CTC_CLI_GET_ARGC_INDEX("profile");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT32("profile", xdata_prof.prof_id, argv[index+1]);
    }

    index = CTC_CLI_GET_ARGC_INDEX("array-map");
    if (0xFF != index)
    {
        xdata_prof.num = ctc_cmd_get_map_array(0,(void*) (xdata_map),argv[index+1]);
        xdata_prof.map = xdata_map;
    }

    if(g_ctcs_api_en)
    {
        ret = ctcs_xdata_set_profile(g_api_ldev, &xdata_prof);
    }
    else
    {
        ret = ctc_xdata_set_profile(&xdata_prof);
    }

    if (ret < 0)
    {
        ctc_cli_out("%% %s \n", ctc_get_error_desc(ret));
        return CLI_ERROR;
    }
	
	return ret;
}

CTC_CLI(ctc_cli_xdata_set_local,
           ctc_cli_xdata_set_local_cmd,
           "xdata (scl  | scl-egs | flow-hash | flow-hash-ext | ipfix | ipfix-egs ) local (mode MODE) (array-map MAP |)",
           "XData",
           "SCL",
           "SCL-EGS",
           "FLOW-HASH",
           "FLOW-HASH-EXT",
           "IPFIX",
           "IPFIX-EGS",
           "Local",
           "Mode",
           "0, only use xdata in the path;1, only use local fixed fields;2, use local fixed fields replace xdata in the path",
           "Map array of generate local xdata",
           "Two-dimensional Array,array number is ctc_xdata_map_t,format is [[WIDTH ,SRC-OFFSET,DST-OFFSET],[...]].For example based on scl,[[4,124,64],[4,120,68]]")

{
    int32 ret = CLI_SUCCESS;
    uint8 index = 0;
 
    ctc_xdata_local_t xdata_local;
	ctc_xdata_map_t   xdata_map[35];
			  
	sal_memset(&xdata_local, 0, sizeof(ctc_xdata_local_t));
	sal_memset(xdata_map, 0, sizeof(ctc_xdata_map_t)*35);

	index = CTC_CLI_GET_ARGC_INDEX("scl");
	if (0xFF != index)
    {
        xdata_local.type=CTC_XDATA_LOCAL_TYPE_SCL;
	}
			  
	index = CTC_CLI_GET_ARGC_INDEX("scl-egs");
	if (0xFF != index)
	{
        xdata_local.type=CTC_XDATA_LOCAL_TYPE_EGS_SCL;
	}
			  
	index = CTC_CLI_GET_ARGC_INDEX("flow-hash");
	if (0xFF != index)
	{
        xdata_local.type=CTC_XDATA_LOCAL_TYPE_FLOW_HASH;
	}
			  
	index = CTC_CLI_GET_ARGC_INDEX("flow-hash-ext");
    if (0xFF != index)
	{
        xdata_local.type=CTC_XDATA_LOCAL_TYPE_FLOW_HASH_EXT;
	}
			  
	index = CTC_CLI_GET_ARGC_INDEX("ipfix");
	if (0xFF != index)
	{
        xdata_local.type=CTC_XDATA_LOCAL_TYPE_IPFIX;
	}
			  
	index = CTC_CLI_GET_ARGC_INDEX("ipfix-egs");
	if (0xFF != index)
	{
        xdata_local.type=CTC_XDATA_LOCAL_TYPE_EGS_IPFIX;
	}

    index = CTC_CLI_GET_ARGC_INDEX("mode");
	if (0xFF != index)
	{
        CTC_CLI_GET_UINT8("mode", xdata_local.mode, argv[index+1]);
	}

    index = CTC_CLI_GET_ARGC_INDEX("array-map");
    if (0xFF != index)
    {
        xdata_local.num = ctc_cmd_get_map_array(0,(void*) (xdata_map),argv[index+1]);
		xdata_local.fields = xdata_map;
    }

	if(g_ctcs_api_en)
    {
        ret = ctcs_xdata_set_local(g_api_ldev, &xdata_local);
    }
    else
    {
        ret = ctc_xdata_set_local(&xdata_local);
    }
			  
    if (ret < 0)
    {
        ctc_cli_out("%% %s \n", ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

	return ret;
			  
}

CTC_CLI(ctc_cli_xdata_set_path,
           ctc_cli_xdata_set_path_cmd,
           "xdata path (ipe-bsr  | ipe-localbsr | bsr-epe | epe-loop0 | epe-loop1  |loop0-ipe | loop1-ipe ) (profile PROFILE) (stacking-en|){array-map MAP | "XDATA_PATH " | } ",
           "XData",
           "Path",
           "IPE_BSR",
           "IPE_LOCAL_BSR",
           "BSR_EPE",
           "EPE_LOOP0",
           "EPE_LOOP1",
           "LOOP0_IPE",
           "LOOP1_IPE",
           "Xdata profile id",
           "Xdata profile id value ",
           "Stacking enable",
           "Map array of path-xdata to path-xdata",
           "Two-dimensional Array,array number is ctc_xdata_map_t,format is [[WIDTH ,SRC-OFFSET,DST-OFFSET],[...]].For example based on ipe-bsr,[[4,0,0],[4,4,4],[4,8,8],[4,12,12],[4,16,16]]",
           XDATA_PATH_STR)
           
{
	int32 ret = CLI_SUCCESS;
	uint8 index = 0;
	
	ctc_xdata_path_t xdata_path;
	ctc_xdata_map_t  xdata_map[35];
	
	sal_memset(&xdata_path, 0, sizeof(ctc_xdata_path_t));
	sal_memset(xdata_map, 0, sizeof(ctc_xdata_map_t)*35);

	index = CTC_CLI_GET_ARGC_INDEX("ipe-bsr");
	if (0xFF != index)
	{
		xdata_path.type=CTC_XDATA_PATH_TYPE_IPE_BSR;
    }

	index = CTC_CLI_GET_ARGC_INDEX("ipe-localbsr");
	if (0xFF != index)
	{
		xdata_path.type=CTC_XDATA_PATH_TYPE_IPE_LOCAL_BSR;
    }
			

	index = CTC_CLI_GET_ARGC_INDEX("bsr-epe");
	if (0xFF != index)
	{
		xdata_path.type=CTC_XDATA_PATH_TYPE_BSR_EPE;
    }

	index = CTC_CLI_GET_ARGC_INDEX("epe-loop0");
	if (0xFF != index)
	{
		xdata_path.type=CTC_XDATA_PATH_TYPE_EPE_LOOP0;
    }

	index = CTC_CLI_GET_ARGC_INDEX("epe-loop1");
	if (0xFF != index)
	{
		xdata_path.type=CTC_XDATA_PATH_TYPE_EPE_LOOP1;
    }

	index = CTC_CLI_GET_ARGC_INDEX("loop0-ipe");
	if (0xFF != index)
	{
		xdata_path.type=CTC_XDATA_PATH_TYPE_LOOP0_IPE;
    }

	index = CTC_CLI_GET_ARGC_INDEX("loop1-ipe");
	if (0xFF != index)
	{
		xdata_path.type=CTC_XDATA_PATH_TYPE_LOOP1_IPE;
    }

	index = CTC_CLI_GET_ARGC_INDEX("profile");
	if (0xFF != index)
    {
        CTC_CLI_GET_UINT32("profile", xdata_path.prof_id, argv[index+1]);
    }

    index = CTC_CLI_GET_ARGC_INDEX("array-map");
    if (0xFF != index)
    {
        xdata_path.num = ctc_cmd_get_map_array(0,(void*) (xdata_map),argv[index+1]);
		xdata_path.map = xdata_map;
    }
	
	index = CTC_CLI_GET_ARGC_INDEX("logic-port-ext");
	if (0xFF != index)
    {
        xdata_path.fixed_bmp |= CTC_XDATA_FIXED_FIELD_LOGIC_PORT_EXT;
    }

	index = CTC_CLI_GET_ARGC_INDEX("hash-value");
	if (0xFF != index)
    {
        xdata_path.fixed_bmp |= CTC_XDATA_FIXED_FIELD_HASH_VALUE;
    }

	index = CTC_CLI_GET_ARGC_INDEX("nat-l4-src-port");
	if (0xFF != index)
    {
        xdata_path.fixed_bmp |= CTC_XDATA_FIXED_FIELD_NAT_L4_SRC_PORT;
    }

	index = CTC_CLI_GET_ARGC_INDEX("nat-l4-dst-port");
	if (0xFF != index)
    {
        xdata_path.fixed_bmp |= CTC_XDATA_FIXED_FIELD_NAT_L4_DST_PORT;
    }

	index = CTC_CLI_GET_ARGC_INDEX("ecmp-hash-high");
	if (0xFF != index)
    {
        xdata_path.fixed_bmp |= CTC_XDATA_FIXED_FIELD_ECMP_HASH_HIGH;
    }

	index = CTC_CLI_GET_ARGC_INDEX("aps-protecting-en");
	if (0xFF != index)
    {
        xdata_path.fixed_bmp |= CTC_XDATA_FIXED_FIELD_APS_PROTECTING_EN;
    }

	index = CTC_CLI_GET_ARGC_INDEX("fwd-type");
	if (0xFF != index)
    {
        xdata_path.fixed_bmp |= CTC_XDATA_FIXED_FIELD_FWD_TYPE;
    }

	index = CTC_CLI_GET_ARGC_INDEX("l3if-id");
	if (0xFF != index)
    {
        xdata_path.fixed_bmp |= CTC_XDATA_FIXED_FIELD_L3IF_ID;
    }

	index = CTC_CLI_GET_ARGC_INDEX("efd");
	if (0xFF != index)
    {
        xdata_path.fixed_bmp |= CTC_XDATA_FIXED_FIELD_EFD;
    }

	index = CTC_CLI_GET_ARGC_INDEX("dnat-l4-dst-port");
	if (0xFF != index)
    {
        xdata_path.fixed_bmp |= CTC_XDATA_FIXED_FIELD_DNAT_L4_DST_PORT;
    }

	index = CTC_CLI_GET_ARGC_INDEX("ingress-en");
	if (0xFF != index)
    {
        xdata_path.fixed_bmp |= CTC_XDATA_FIXED_FIELD_INGRESS_EN;
    }

    index = CTC_CLI_GET_ARGC_INDEX("stacking-en");
    if (0xFF != index)
    {
        xdata_path.flag |= CTC_XDATA_PATH_STACKING_EN;
    }

    if(g_ctcs_api_en)
    {
        ret = ctcs_xdata_set_path(g_api_ldev, &xdata_path);
    }
    else
    {
        ret = ctc_xdata_set_path(&xdata_path);
    }
			  	
    if (ret < 0)
    {
        ctc_cli_out("%% %s \n", ctc_get_error_desc(ret));
        return CLI_ERROR;
    }
	
    return ret;
}

CTC_CLI(ctc_cli_xdata_get_profile,
          ctc_cli_xdata_get_profile_cmd,
          "show xdata ((post (scl | acl | tunnel | l3if | forward) ) | (scl | tunnel | mpls | fdb | ipuc | flow | acl | scl-egs | acl-egs)) (profile PROFILE) ",
          "Show",
          "XData module",
          "Infomation after module,main is packetinfo",
          "SCL ingress",
          "ACL ingress",
          "TUNNEL",
          "L3IF",
          "FORWARD",
          "SCL ingress",
          "TUNNEL",
          "MPLS",
          "FDB-MACDA",
          "IPUC-IPDA",
          "FLOW",
          "ACL ingress",
          "SCL egress",
          "ACL egress",
          "Xdata profile id",
          "Xdata profile id value ")
{   
    int32  ret = CLI_SUCCESS;

    ctc_xdata_prof_t xdata_prof;
    ctc_xdata_map_t  xdata_map[35];
    uint8 index = 0;
    uint8 post_idx = 1;
    uint8 ad_idx = 0;
    uint8 map_loop = 0;
    char* prof_name[]={"POST SCL","POST L3IF","POST TUNNEL","POST FWD","POST ACL",\
                       "SCL","TUNNEL","MPLS","FDB","IPUC","FLOW","ACL","MET","EGS SCL","EGS ACL"};

    sal_memset(&xdata_prof, 0, sizeof(ctc_xdata_prof_t));
    sal_memset(&xdata_map, 0, sizeof(ctc_xdata_map_t)*35);
    xdata_prof.map = xdata_map;

    index = CTC_CLI_GET_RANGE_INDEX("scl",post_idx,post_idx+1);
    if (0xFF != index)
    {
        xdata_prof.type = CTC_XDATA_PROF_TYPE_POST_SCL;
    }
    index = CTC_CLI_GET_RANGE_INDEX("acl",post_idx,post_idx+1);
    if (0xFF != index) 
    {
        xdata_prof.type = CTC_XDATA_PROF_TYPE_POST_ACL;
    }
    index = CTC_CLI_GET_RANGE_INDEX("tunnel",post_idx,post_idx+1);
    if (0xFF != index)
    {
        xdata_prof.type = CTC_XDATA_PROF_TYPE_POST_TUNNEL;
    }
    index = CTC_CLI_GET_RANGE_INDEX("l3if",post_idx,post_idx+1);
    if (0xFF != index)
    {
        xdata_prof.type = CTC_XDATA_PROF_TYPE_POST_L3IF;
    }
    index = CTC_CLI_GET_RANGE_INDEX("forward",post_idx,post_idx+1);
    if (0xFF != index)
    {
        xdata_prof.type = CTC_XDATA_PROF_TYPE_POST_FWD;
    }

    index = CTC_CLI_GET_RANGE_INDEX("scl",ad_idx,ad_idx+1);
    if (0xFF != index)
    {
        xdata_prof.type = CTC_XDATA_PROF_TYPE_DSSCL;
    }
    index = CTC_CLI_GET_RANGE_INDEX("tunnel",ad_idx,ad_idx+1);
    if (0xFF != index)
    {
        xdata_prof.type = CTC_XDATA_PROF_TYPE_DSTUNNEL;
    }
    index = CTC_CLI_GET_RANGE_INDEX("mpls",ad_idx,ad_idx+1);
    if (0xFF != index)
    {
        xdata_prof.type = CTC_XDATA_PROF_TYPE_DSMPLS;
    }
    index = CTC_CLI_GET_RANGE_INDEX("fdb",ad_idx,ad_idx+1);
    if (0xFF != index)
    {
        xdata_prof.type = CTC_XDATA_PROF_TYPE_DSMACDA;
    }
    index = CTC_CLI_GET_RANGE_INDEX("ipuc",ad_idx,ad_idx+1);
    if (0xFF != index)
    {
        xdata_prof.type = CTC_XDATA_PROF_TYPE_DSIPDA;
    }
    index = CTC_CLI_GET_RANGE_INDEX("flow",ad_idx,ad_idx+1);
    if (0xFF != index)
    {
        xdata_prof.type = CTC_XDATA_PROF_TYPE_DSFLOW;
    }
    index = CTC_CLI_GET_RANGE_INDEX("acl",ad_idx,ad_idx+1);
    if (0xFF != index)
    {
        xdata_prof.type = CTC_XDATA_PROF_TYPE_DSACL;
    }
    index = CTC_CLI_GET_RANGE_INDEX("scl-egs",ad_idx,ad_idx+1);
    if (0xFF != index)
    {
        xdata_prof.type = CTC_XDATA_PROF_TYPE_EGS_DSSCL;
    }
    index = CTC_CLI_GET_RANGE_INDEX("acl-egs",ad_idx,ad_idx+1);
    if (0xFF != index)
    {
        xdata_prof.type = CTC_XDATA_PROF_TYPE_EGS_DSACL;
    }

    index = CTC_CLI_GET_ARGC_INDEX("profile");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT32("profile", xdata_prof.prof_id, argv[index+1]);
    }

    if(g_ctcs_api_en)
    {
        ret = ctcs_xdata_get_profile(g_api_ldev, &xdata_prof);
    }
    else
    {
        ret = ctc_xdata_get_profile(&xdata_prof);
    }

    if (ret < 0)
    {
        ctc_cli_out("%% %s \n", ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    ctc_cli_out("---------- XDATA Profile ----------\n");
    ctc_cli_out("%-12s Profile: %d      Num: %d\n", prof_name[xdata_prof.type],xdata_prof.prof_id,xdata_prof.num);
    ctc_cli_out("-----------------------------------\n");
    ctc_cli_out("Id  Width   Src-offset   Dst-offset\n");
    ctc_cli_out("-----------------------------------\n");

    for(map_loop=0;map_loop<xdata_prof.num;map_loop++)
    {
        ctc_cli_out("%d", map_loop);
        ctc_cli_out("%6d", xdata_map[map_loop].width);
        ctc_cli_out("%11d", xdata_map[map_loop].src_offset);
        ctc_cli_out("%12d", xdata_map[map_loop].dst_offset);
        ctc_cli_out("\n");
    }
    ctc_cli_out("\n");

    return ret;

}


CTC_CLI(ctc_cli_xdata_get_local,
           ctc_cli_xdata_get_local_cmd,
           "show xdata (scl  | scl-egs | flow-hash | flow-hash-ext | ipfix | ipfix-egs ) local  ",
           "Show",
           "XData",
           "SCL",
           "SCL-EGS",
           "FLOW-HASH",
           "FLOW-HASH-EXT",
           "IPFIX",
           "IPFIX-EGS",
           "Local")
{
    int32 ret = CLI_SUCCESS;
    uint8 index = 0;
    
    ctc_xdata_local_t xdata_local;
    ctc_xdata_map_t   xdata_map[35];
    uint8 map_loop = 0;
    char* local_name[]={"SCL","EGS SCL","FLOW HASH","FLOW HASH EXT","IPFIX","EGS IPFIX"};

    sal_memset(&xdata_local, 0, sizeof(ctc_xdata_local_t));
    sal_memset(xdata_map, 0, sizeof(ctc_xdata_map_t)*35);
    xdata_local.fields=xdata_map;

    index = CTC_CLI_GET_ARGC_INDEX("scl");
    if (0xFF != index)
    {
        xdata_local.type=CTC_XDATA_LOCAL_TYPE_SCL;
    }
    
    index = CTC_CLI_GET_ARGC_INDEX("scl-egs");
    if (0xFF != index)
    {
        xdata_local.type=CTC_XDATA_LOCAL_TYPE_EGS_SCL;
    }
    
    index = CTC_CLI_GET_ARGC_INDEX("flow-hash");
    if (0xFF != index)
    {
        xdata_local.type=CTC_XDATA_LOCAL_TYPE_FLOW_HASH;
    }
    
    index = CTC_CLI_GET_ARGC_INDEX("flow-hash-ext");
    if (0xFF != index)
    {
        xdata_local.type=CTC_XDATA_LOCAL_TYPE_FLOW_HASH_EXT;
    }
    
    index = CTC_CLI_GET_ARGC_INDEX("ipfix");
    if (0xFF != index)
    {
        xdata_local.type=CTC_XDATA_LOCAL_TYPE_IPFIX;
    }
    
    index = CTC_CLI_GET_ARGC_INDEX("ipfix-egs");
    if (0xFF != index)
    {
        xdata_local.type=CTC_XDATA_LOCAL_TYPE_EGS_IPFIX;
    }

    if(g_ctcs_api_en)
    {
        ret = ctcs_xdata_get_local(g_api_ldev, &xdata_local);
    }
    else
    {
        ret = ctc_xdata_get_local(&xdata_local);
    }

    if (ret < 0)
    {
        ctc_cli_out("%% %s \n", ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    ctc_cli_out("----------- XDATA Local -----------\n");
    ctc_cli_out("%-12s  Mode: %d        Num: %d\n", local_name[xdata_local.type],xdata_local.mode,xdata_local.num);
    ctc_cli_out("-----------------------------------\n");
    if(xdata_local.mode == 2)
    {
        ctc_cli_out("Id  Width   Src-offset   Dst-offset\n");
        ctc_cli_out("-----------------------------------\n");
        for(map_loop=0;map_loop<xdata_local.num;map_loop++)
        {
            ctc_cli_out("%d", map_loop);
            ctc_cli_out("%6d", xdata_map[map_loop].width);
            ctc_cli_out("%11d", xdata_map[map_loop].src_offset);
            ctc_cli_out("%12d", xdata_map[map_loop].dst_offset);
            ctc_cli_out("\n");
        }
    }

    ctc_cli_out("\n");


    return ret;
}

CTC_CLI(ctc_cli_xdata_get_path,
           ctc_cli_xdata_get_path_cmd,
           "show xdata path (ipe-bsr  | ipe-localbsr | bsr-epe | epe-loop0 | epe-loop1  |loop0-ipe | loop1-ipe ) (profile PROFILE) ",
           "Show",
           "XData",
           "Path",
           "IPE_BSR",
           "IPE_LOCAL_BSR",
           "BSR_EPE",
           "EPE_LOOP0",
           "EPE_LOOP1",
           "LOOP0_IPE",
           "LOOP1_IPE",
           "Xdata profile id",
           "Xdata profile id value ")
           
{
    int32 ret = CLI_SUCCESS;
    uint8 index = 0;

    ctc_xdata_path_t xdata_path;
    ctc_xdata_map_t  xdata_map[35];
    uint8 map_loop = 0;
    char* path_name[]={"IPE-BSR","IPE-LOCAL BSR","BSR-EPE","EPE-LOOP0","EPE-LOOP1","LOOP0-IPE","LOOP1-IPE"};

    sal_memset(&xdata_path, 0, sizeof(ctc_xdata_path_t));
    sal_memset(xdata_map, 0, sizeof(ctc_xdata_map_t)*35);
    xdata_path.map=xdata_map;

    index = CTC_CLI_GET_ARGC_INDEX("ipe-bsr");
    if (0xFF != index)
    {
        xdata_path.type=CTC_XDATA_PATH_TYPE_IPE_BSR;
    }
    
    index = CTC_CLI_GET_ARGC_INDEX("ipe-localbsr");
    if (0xFF != index)
    {
        xdata_path.type=CTC_XDATA_PATH_TYPE_IPE_LOCAL_BSR;
    }
    
    index = CTC_CLI_GET_ARGC_INDEX("bsr-epe");
    if (0xFF != index)
    {
        xdata_path.type=CTC_XDATA_PATH_TYPE_BSR_EPE;
    }
    
    index = CTC_CLI_GET_ARGC_INDEX("epe-loop0");
    if (0xFF != index)
    {
        xdata_path.type=CTC_XDATA_PATH_TYPE_EPE_LOOP0;
    }
    
    index = CTC_CLI_GET_ARGC_INDEX("epe-loop1");
    if (0xFF != index)
    {
        xdata_path.type=CTC_XDATA_PATH_TYPE_EPE_LOOP1;
    }
    
    index = CTC_CLI_GET_ARGC_INDEX("loop0-ipe");
    if (0xFF != index)
    {
        xdata_path.type=CTC_XDATA_PATH_TYPE_LOOP0_IPE;
    }
    
    index = CTC_CLI_GET_ARGC_INDEX("loop1-ipe");
    if (0xFF != index)
    {
        xdata_path.type=CTC_XDATA_PATH_TYPE_LOOP1_IPE;
    }
    
    index = CTC_CLI_GET_ARGC_INDEX("profile");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT32("profile", xdata_path.prof_id, argv[index+1]);
    }

    if(g_ctcs_api_en)
    {
        ret = ctcs_xdata_get_path(g_api_ldev, &xdata_path);
    }
    else
    {
        ret = ctc_xdata_get_path(&xdata_path);
    }

    if (ret < 0)
    {
        ctc_cli_out("%% %s \n", ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    ctc_cli_out("------------ XDATA Path -----------\n");
    ctc_cli_out("%-12s Profile: %d      Num: %d\n", path_name[xdata_path.type],xdata_path.prof_id,xdata_path.num);
    ctc_cli_out("-----------------------------------\n");
    ctc_cli_out("Id  Width   Src-offset   Dst-offset\n");
    ctc_cli_out("-----------------------------------\n");
    for(map_loop=0;map_loop<xdata_path.num;map_loop++)
    {
        ctc_cli_out("%d", map_loop);
        ctc_cli_out("%6d", xdata_map[map_loop].width);
        ctc_cli_out("%11d", xdata_map[map_loop].src_offset);
        ctc_cli_out("%12d", xdata_map[map_loop].dst_offset);
        ctc_cli_out("\n");
    }
    ctc_cli_out("Flag:%u \n",xdata_path.fixed_bmp);
    ctc_cli_out("\n");

    return ret;
}


int32
ctc_xdata_cli_init(void)
{
    install_element(CTC_SDK_MODE, &ctc_cli_xdata_set_profile_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_xdata_set_local_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_xdata_set_path_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_xdata_get_profile_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_xdata_get_local_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_xdata_get_path_cmd);

    return CLI_SUCCESS;
}

int32
ctc_xdata_cli_deinit(void)
{
    uninstall_element(CTC_SDK_MODE, &ctc_cli_xdata_set_profile_cmd);
    uninstall_element(CTC_SDK_MODE, &ctc_cli_xdata_set_local_cmd);
    uninstall_element(CTC_SDK_MODE, &ctc_cli_xdata_set_path_cmd);
    uninstall_element(CTC_SDK_MODE, &ctc_cli_xdata_get_profile_cmd);
    uninstall_element(CTC_SDK_MODE, &ctc_cli_xdata_get_local_cmd);
    uninstall_element(CTC_SDK_MODE, &ctc_cli_xdata_get_path_cmd);

    return CLI_SUCCESS;
}


